package pl.vanta.mjuzik2.impl.player.formats;

import java.util.HashMap;
import java.util.Map;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioFileFormat.Type;

import pl.vanta.mjuzik2.api.FileInfo;

public abstract class AbstractFileInfo implements FileInfo
{
	protected Map<String, Object>	properties;
	protected Map<String, String>	propertiesDescription;

	protected AudioFileFormat.Type	type;

	protected String				album;
	protected String				artist;
	protected int					bitRate;
	protected int					channels;
	protected String				comment;
	protected String				genre;
	protected long					playtime;
	protected int					samplingRate;
	protected String				title;
	protected int					track;
	protected String				year;

	public AbstractFileInfo()
	{
		this.properties = new HashMap<String, Object>();
		this.propertiesDescription = new HashMap<String, String>();
	}

	public static Map<String, Object> getMusicFilesPropertiesMap(AudioFileFormat audioFileFormat)
	{
		Map<String, Object> properties = new HashMap<String, Object>();

		// Add JavaSound properties.
		if (audioFileFormat.getByteLength() > 0)
			properties.put("audio.length.bytes", new Integer(audioFileFormat.getByteLength()));
		if (audioFileFormat.getFrameLength() > 0)
			properties.put("audio.length.frames", new Integer(audioFileFormat.getFrameLength()));
		if (audioFileFormat.getType() != null)
			properties.put("audio.type", (audioFileFormat.getType().toString()));

		// Audio format.
		AudioFormat audioFormat = audioFileFormat.getFormat();
		if (audioFormat.getFrameRate() > 0)
			properties.put("audio.framerate.fps", new Float(audioFormat.getFrameRate()));
		if (audioFormat.getFrameSize() > 0)
			properties.put("audio.framesize.bytes", new Integer(audioFormat.getFrameSize()));
		if (audioFormat.getSampleRate() > 0)
			properties.put("audio.samplerate.hz", new Float(audioFormat.getSampleRate()));
		if (audioFormat.getSampleSizeInBits() > 0)
			properties.put("audio.samplesize.bits", new Integer(audioFormat.getSampleSizeInBits()));
		if (audioFormat.getChannels() > 0)
			properties.put("audio.channels", new Integer(audioFormat.getChannels()));

		return properties;
	}

	@Override
	public final boolean load(AudioFileFormat format)
	{
		this.type = format.getType();

		boolean result = loadFormatSpecificInfo(format);

		this.properties.putAll(getMusicFilesPropertiesMap(format));

		return result;
	}

	protected abstract boolean loadFormatSpecificInfo(AudioFileFormat aff);

	@Override
	public Map<String, Object> getProperties()
	{
		return this.properties;
	}

	@Override
	public Map<String, String> getPropertiesDescriptions()
	{
		return this.propertiesDescription;
	}

	@Override
	public String getAlbum()
	{
		return this.album;
	}

	@Override
	public String getArtist()
	{
		return this.artist;
	}

	@Override
	public int getBitRate()
	{
		return this.bitRate;
	}

	@Override
	public int getChannels()
	{
		return this.channels;
	}

	@Override
	public String getComment()
	{
		return this.comment;
	}

	@Override
	public String getGenre()
	{
		return this.genre;
	}

	@Override
	public long getPlayTime()
	{
		return this.playtime;
	}

	@Override
	public int getSamplingRate()
	{
		return this.samplingRate;
	}

	@Override
	public String getTitle()
	{
		return this.title;
	}

	@Override
	public int getTrack()
	{
		return this.track;
	}

	@Override
	public String getYear()
	{
		return this.year;
	}

	@Override
	public Type getType()
	{
		return this.type;
	}
}